/*
**************************************************************************************
*Myriad Engine                                                                       *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
package leola.types;

import leola.ast.Stmt;
import leola.backend.interpreter.Scope;
import leola.backend.interpreter.SymbolTable;


/**
 * Defines a class instance
 * 
 * @author Tony
 *
 */
public class LeoClass extends LeoScopedObject {

	/**
	 * CLass body
	 */
	private Stmt classBody;
	
	/**
	 * Super class if available
	 */
	private LeoObject superClass;
	
	/**
	 * Class name
	 */
	private String className;
	
	/**
	 * @param type
	 */
	public LeoClass(Scope classScope, String className, Stmt classBody, LeoObject superClass) {
		super(LeoType.CLASS, classScope);
		
		this.className = className;
		this.superClass = superClass;
		this.classBody = classBody;
		
		SymbolTable table = getScope().getSymbolTable();		
		if ( superClass != null && superClass.isOfType(LeoType.CLASS)) {
			LeoClass sc = superClass.as();
			table.set(sc.getScope().getSymbolTable());
		}
		
		table.put("this", this);
		table.put("super", superClass);		

		addMethod("hasProperty", String.class);
		addMethod("getProperty", String.class);
	}
	
	
	
	/**
	 * @param name
	 * @return true if this class has the requested property
	 */
	public boolean hasProperty(String name) {
		return getScope().getSymbolTable().get(name) != null;
	}
	
	/**
	 * Gets a property from the class.
	 * 
	 * @param name
	 * @return
	 */
	public LeoObject getProperty(String name) {
		return getScope().getSymbolTable().get(name);
	}
	
	/**
	 * @return the superClass
	 */
	public LeoObject getSuperClass() {
		return superClass;
	}
	
	/**
	 * @return the className
	 */
	public String getClassName() {
		return className;
	}
	
	/**
	 * @return the classBody
	 */
	public Stmt getClassBody() {
		return classBody;
	}

	/* (non-Javadoc)
	 * @see leola.types.LeoObject#eq(leola.types.LeoObject)
	 */
	@Override
	public boolean eq(LeoObject other) {
		boolean isEquals = false;
		
		if ( other != null ) {
			if ( other.isOfType(LeoType.CLASS) ) {
				LeoClass aClass = other.as();
				SymbolTable thisTable = getScope().getSymbolTable();
				isEquals = thisTable.leoEquals(aClass.getScope().getSymbolTable());
			}
		}
		return isEquals;
	}

	/* (non-Javadoc)
	 * @see leola.types.LeoObject#gt(leola.types.LeoObject)
	 */
	@Override
	public boolean gt(LeoObject other) {
		return false;
	}

	/* (non-Javadoc)
	 * @see leola.types.LeoObject#lt(leola.types.LeoObject)
	 */
	@Override
	public boolean lt(LeoObject other) {
		return false;
	}

	/* (non-Javadoc)
	 * @see leola.types.LeoObject#getValue()
	 */
	@Override
	public Object getValue() {
		return this;
	}
	
	/* (non-Javadoc)
	 * @see leola.types.LeoObject#clone()
	 */
	@Override
	public LeoObject clone() {
		LeoObject clonedSuperClass = (this.superClass != null) ? this.superClass.clone() : null;
		return new LeoClass(getScope().clone(), this.className, getClassBody(), clonedSuperClass);
	}
}
